#pragma once

#include<list>

using namespace std;

template<class T>
class DoublyList:
  public list<T>
{
private:
  typename list<T>::iterator          m_forw_iterator;
  typename list<T>::reverse_iterator  m_rev_iterator;

public:
  DoublyList(void);
  ~DoublyList(void);
  void AddElement(const T &);
  void RemoveElement(const T &);
  const T & GetNext(const T &);
  const T & GetPrev(const T &);
protected:
  void FindElementIterator(const T &);
  void Test();
};



template<class T>
DoublyList<T>::DoublyList(void)
{
}

template<class T>
DoublyList<T>::~DoublyList(void)
{
}

template<class T>
void DoublyList<T>::AddElement(const T & t)
{
  this->push_back(t);
}

template<class T>
const T & DoublyList<T>::GetNext(const T & t)
{
  FindElementIterator(t);
  _ASSERT (m_forw_iterator != list<T>::end());
  
  m_forw_iterator++;
  if(m_forw_iterator == list<T>::end())
    m_forw_iterator = list<T>::begin();
  return (*m_forw_iterator);
}

template<class T>
const T & DoublyList<T>::GetPrev(const T & t)
{
  FindElementIterator(t);
  _ASSERT (m_forw_iterator != list<T>::end());
  
  if(m_forw_iterator == list<T>::begin())
    m_forw_iterator = list<T>::end();
  return (*(--m_forw_iterator));
}

template<class T>
void DoublyList<T>::RemoveElement(const T & t)
{
  remove(t);
}

template<class T>
void DoublyList<T>::FindElementIterator(const T & t)
{
  m_forw_iterator = list<T>::begin();
  
  while( m_forw_iterator != list<T>::end() && ((*m_forw_iterator) != t))
  {
    m_forw_iterator++;
  }
}


template<class T>
void DoublyList<T>::Test()
{
  T t;
  m_rev_iterator = list<T>::rbegin();
  while(m_rev_iterator != list<T>::rend())
  {
    t = *m_rev_iterator;
    m_rev_iterator++;
  }
}